#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
'''
@author: yuejl
@application:
@contact: lewyuejian@163.com
@file: compat.py
@time: 2021/3/20 0020 17:12
@desc: 兼容
'''
from typing import Dict, Any, List
from mobs.utils.loadUtils import FileUtils
from wechatapi.exceptions import TestCaseFormatError

def sort_dict_by_custom_order(raw_dict: Dict, custom_order: List):
    '''
    sorted(d.items(), key=lambda x: x[1]) 中 d.items() 为待排序的对象；
    key=lambda x: x[1] 为对前面的对象中的第二维数据（即value）的值进行排序。 key=lambda 变量：变量[维数] 。
    维数可以按照自己的需要进行设置。

    :param raw_dict:
    :param custom_order:
    :return:
    '''

    def get_index_from_list(lst: List, item: Any):
        try:
            return lst.index(item)
        except ValueError:
            # item is not in lst
            return len(lst) + 1

    return dict(
        sorted(raw_dict.items(), key=lambda i: get_index_from_list(custom_order, i[0]))
    )

def _sort_request_by_custom_order(request: Dict) -> Dict:

    '''
    Args:
        request(dict)，按照 custom_order 的元素进行排序

    Examples:
        .data\test.yaml
        >>>
        testcase:
            name: 'login'
            teststeps:
                method: 'GET'
                url: https://ceshiren.com/
                json: {
                        t: 'gd'
                }
                headers:
                  Accept-Language: zh-CN,zh;q=0.9,zh-HK;q=0.8
                  accept-encoding: gzip, deflate, br

        >>> api_content = FileUtils().load_file('.data\test.yaml')
        >>> teststep = {"request": _sort_request_by_custom_order(api_content["teststeps"]),}

    Returns:
        {'request':
            {
                'method': 'GET',
                'url': 'https://ceshiren.com/',
                'headers':
                    {
                        'Accept-Language':
                            'zh-CN,zh;q=0.9,zh-HK;q=0.8',
                            'accept-encoding': 'gzip, deflate, br'
                    }
                'json':
                    {
                    't': 'gd'
                    }
            }
        }
    :param request:
    :return:
    '''
    custom_order = [
        "method",
        "url",
        "params",
        "headers",
        "cookies",
        "data",
        "json",
        "files",
        "timeout",
        "allow_redirects",
        "proxies",
        "verify",
        "stream",
        "auth",
        "cert",
    ]
    return sort_dict_by_custom_order(request, custom_order)

def _sort_step_by_custom_order(teststep: Dict) -> Dict:
    custom_order = [
        "name",
        "request",
        "extract",
        "expect",

    ]
    return sort_dict_by_custom_order(teststep, custom_order)

def _sort_data_dict_by_custom_order(data: Dict) -> Dict:
    custom_order = [
        "method",
        "url",
        "tips",
        "testcase",
    ]
    return sort_dict_by_custom_order(data, custom_order)

def _sort_action_dict_by_custom_order(data: Dict) -> Dict:
    custom_order = [
        "apiname",
        "method",
        "url",
        "depend_data",
        "tips",
        "action",

    ]
    return sort_dict_by_custom_order(data, custom_order)

def _sort_testcase_dict_by_custom_order(data: Dict) -> Dict:
    custom_order = [
        "apiname",
        "method",
        "url",
        "depend_data",
        "tips",
        "name",
        "descript",
        "case_id",
        "case_title",
        "priority",
        "demo",
        "doc",
        "json",
        'expect'

    ]
    return sort_dict_by_custom_order(data, custom_order)

def ensure_testcase_attachment(api_content: Dict) -> Dict:
    test_dict = {
        "apiname": api_content.get("apiname")
    }

    if "method" in api_content:
        test_dict["method"] = api_content.get("method")

    if "url" in api_content:
        test_dict["url"] = api_content.get("url")
    if "depend_data" in api_content:
        test_dict["depend_data"] = api_content.get("depend_data")
    if "tips" in api_content:
        test_dict["tips"] = api_content.get("tips")

    if "testcase" in api_content:
        if not isinstance(api_content.get("testcase"), Dict):
            raise TestCaseFormatError(
                f'Invalid testcase : {api_content.get("testcase")}'
            )
        a = api_content.get("testcase")
        print(f"testcase -- {a}")
    if "action" in api_content.get("testcase"):
        test_dict["action"] = api_content.get("testcase").get("action")

    return test_dict

def extract_params(content):
    test_dict = {
        "name": content["name"],
    }

    if "url" in content:
        test_dict["url"] = content["url"]

    if "method" in content:
        test_dict["method"] = content["method"]

    if "headers" in content:
        test_dict["headers"] = content["headers"]
    if "json" in content:
        test_dict["json"] = content["headers"]
    if "data" in content:
        test_dict["data"] = content["data"]
    if "params" in content:
        test_dict["params"] = content["params"]
    if "timeout" in content:
        test_dict["timeout"] = content["timeout"]
    if "files" in content:
        test_dict["files"] = content["files"]

    return test_dict

def ensure_testcase_api(api_content: Dict) -> Dict:

    teststep = {
        "request": _sort_request_by_custom_order(api_content["teststeps"]),
    }
    teststep.update(extract_params(api_content))

    teststep = _sort_step_by_custom_order(teststep)

    return teststep

